// 手写promise： 参考 等待者模式

/**
 * 要点：
 * 1. then链式执行
 * 2. then产生新的promise
 * 3. resolve 内部化
 */

new Promise((resolve,reject)=>{

})
class MyPromise{
    constructor(callback){
        // 状态
        this.STATUS_SET = {
            PENDDING: 'pendding',
            RESOLVED: 'resolved',
            REJECTED: 'rejected',
        };
        this.successCallBack = undefined;
        this.failCallBack = undefined;
        this.successInfo =  undefined;
        this.errInfo = undefined;

        this.status = this.STATUS_SET.PENDDING
        this.resolve = this.resolve.bind(this)
        this.reject  = this.reject.bind(this)
        
        this.nextPromise = null // 关联的下一个promise
        this.order = 0 // promise链的位置, 0表示首位
        this.resolveNext = null
        this.rejectNext = null
        callback&&callback instanceof Function&&callback.call(null, this.resolve, this.reject)
    }

    resolve(val){
        // 一次敲定
        if(this.status!=this.STATUS_SET.PENDDING){
            return
        }
        this.status = this.STATUS_SET.RESOLVED
        
        this.successInfo = val
        // 创建微任务，将回调传入微任务队列
        queueMicrotask(()=>{
            // 第一个promise没有回调
            let result = this._excFunc(this.successCallBack,val)
            this.resolveNext&&this.resolveNext( this.order==0 ?this.successInfo: result )
        })
    }
    reject(info){
        if(this.status!=this.STATUS_SET.PENDDING){
            return
        }
        this.status = this.STATUS_SET.REJECTED
        this.errInfo = info
        queueMicrotask(()=>{
            let result = this._excFunc(this.failCallBack,info)
            this.rejectNext&&this.rejectNext( result||this.errInfo )
        })
    }

    _excFunc(func,args){
        return func&&func(args)
    }


    then(onSuccess,onReject){
        let  promise = new MyPromise((resolve,reject)=>{
            this.resolveNext = resolve
            this.rejectNext = reject
        })

        // 上一个 promise 变化如何传递给下一个？
        this.nextPromise = promise
        promise.order = this.order+1
        // 返回等效promise
        onSuccess&&( promise.successCallBack = onSuccess ) 
        onReject&&( promise.failCallBack = onReject )
        
        if(this.status==this.STATUS_SET.RESOLVED){
            this.resolveNext&&this.resolveNext( this.successInfo )
        }else if(this.status==this.STATUS_SET.REJECTED){
            this.rejectNext&&this.rejectNext( this.errInfo )
        }

        return promise
    }
}


console.log('同步1');
const promise = new MyPromise((resolve,reject)=>{
    console.log('京剧');
    setTimeout(()=>{
        resolve('dwqnjkqwd')
    },100)
})

console.log('同步2');
promise.then((args)=>{
    console.log(`接受参数：${args}`);
    return 95
}, (err)=>{
    console.log(`接受异常：${err}`);
}).then((a)=>{
    console.log(`这是下一个then: ${a}`);
})

console.log('同步3');


// Promise.all 发布订阅模式，all订阅参数中所有promise的状态
